-----------------------------------------------
-- Project		: ECE 251 FINAL PROJECT
-- Author 		: Mahmut Yilmaz
-- Last Modified: 04/12/2007
-----------------------------------------------

LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE work.all;

-- To be used with 32-bit of data (4-bytes)
ENTITY crc32_d32 IS
	PORT (	clk     :in  std_logic;
	        reset   :in  std_logic;
	        enable  :in  std_logic;
	        init    :in  std_logic;
	        data_in :in  std_logic_vector (31 downto 0);
	        crc_out :out std_logic_vector (31 downto 0)
			);
END crc32_d32;


architecture behav of crc32_d32 is
    signal crc_reg  :std_logic_vector (31 downto 0);
    signal next_crc :std_logic_vector (31 downto 0);
begin

    crc_out <= crc_reg;
    
    -- CRC Control logic
    process (clk) begin
        if (clk'event and clk='1') then
            if (reset = '1') then
                crc_reg <= x"FFFFFFFF";
            elsif (enable = '1' and init= '1') then
                crc_reg <= next_crc;
            end if;
        end if;
    end process;
    
	-- Parallel CRC calculation
	-- polynomial: (0 1 2 4 5 7 8 10 11 12 16 22 23 26 32)
	-- data width: 32
	-- convention: the first serial data bit is data_in(31)
    next_crc(0) <= data_in(31) xor data_in(30) xor data_in(29) xor data_in(28) xor data_in(26) xor data_in(25) xor 
                 data_in(24) xor data_in(16) xor data_in(12) xor data_in(10) xor data_in(9) xor data_in(6) xor 
                 data_in(0) xor crc_reg(0) xor crc_reg(6) xor crc_reg(9) xor crc_reg(10) xor crc_reg(12) xor 
                 crc_reg(16) xor crc_reg(24) xor crc_reg(25) xor crc_reg(26) xor crc_reg(28) xor crc_reg(29) xor 
                 crc_reg(30) xor crc_reg(31);
    next_crc(1) <= data_in(28) xor data_in(27) xor data_in(24) xor data_in(17) xor data_in(16) xor data_in(13) xor 
                 data_in(12) xor data_in(11) xor data_in(9) xor data_in(7) xor data_in(6) xor data_in(1) xor 
                 data_in(0) xor crc_reg(0) xor crc_reg(1) xor crc_reg(6) xor crc_reg(7) xor crc_reg(9) xor 
                 crc_reg(11) xor crc_reg(12) xor crc_reg(13) xor crc_reg(16) xor crc_reg(17) xor crc_reg(24) xor 
                 crc_reg(27) xor crc_reg(28);
    next_crc(2) <= data_in(31) xor data_in(30) xor data_in(26) xor data_in(24) xor data_in(18) xor data_in(17) xor 
                 data_in(16) xor data_in(14) xor data_in(13) xor data_in(9) xor data_in(8) xor data_in(7) xor 
                 data_in(6) xor data_in(2) xor data_in(1) xor data_in(0) xor crc_reg(0) xor crc_reg(1) xor 
                 crc_reg(2) xor crc_reg(6) xor crc_reg(7) xor crc_reg(8) xor crc_reg(9) xor crc_reg(13) xor 
                 crc_reg(14) xor crc_reg(16) xor crc_reg(17) xor crc_reg(18) xor crc_reg(24) xor crc_reg(26) xor 
                 crc_reg(30) xor crc_reg(31);
    next_crc(3) <= data_in(31) xor data_in(27) xor data_in(25) xor data_in(19) xor data_in(18) xor data_in(17) xor 
                 data_in(15) xor data_in(14) xor data_in(10) xor data_in(9) xor data_in(8) xor data_in(7) xor 
                 data_in(3) xor data_in(2) xor data_in(1) xor crc_reg(1) xor crc_reg(2) xor crc_reg(3) xor 
                 crc_reg(7) xor crc_reg(8) xor crc_reg(9) xor crc_reg(10) xor crc_reg(14) xor crc_reg(15) xor 
                 crc_reg(17) xor crc_reg(18) xor crc_reg(19) xor crc_reg(25) xor crc_reg(27) xor crc_reg(31);
    next_crc(4) <= data_in(31) xor data_in(30) xor data_in(29) xor data_in(25) xor data_in(24) xor data_in(20) xor 
                 data_in(19) xor data_in(18) xor data_in(15) xor data_in(12) xor data_in(11) xor data_in(8) xor 
                 data_in(6) xor data_in(4) xor data_in(3) xor data_in(2) xor data_in(0) xor crc_reg(0) xor 
                 crc_reg(2) xor crc_reg(3) xor crc_reg(4) xor crc_reg(6) xor crc_reg(8) xor crc_reg(11) xor 
                 crc_reg(12) xor crc_reg(15) xor crc_reg(18) xor crc_reg(19) xor crc_reg(20) xor crc_reg(24) xor 
                 crc_reg(25) xor crc_reg(29) xor crc_reg(30) xor crc_reg(31);
    next_crc(5) <= data_in(29) xor data_in(28) xor data_in(24) xor data_in(21) xor data_in(20) xor data_in(19) xor 
                 data_in(13) xor data_in(10) xor data_in(7) xor data_in(6) xor data_in(5) xor data_in(4) xor 
                 data_in(3) xor data_in(1) xor data_in(0) xor crc_reg(0) xor crc_reg(1) xor crc_reg(3) xor 
                 crc_reg(4) xor crc_reg(5) xor crc_reg(6) xor crc_reg(7) xor crc_reg(10) xor crc_reg(13) xor 
                 crc_reg(19) xor crc_reg(20) xor crc_reg(21) xor crc_reg(24) xor crc_reg(28) xor crc_reg(29);
    next_crc(6) <= data_in(30) xor data_in(29) xor data_in(25) xor data_in(22) xor data_in(21) xor data_in(20) xor 
                 data_in(14) xor data_in(11) xor data_in(8) xor data_in(7) xor data_in(6) xor data_in(5) xor 
                 data_in(4) xor data_in(2) xor data_in(1) xor crc_reg(1) xor crc_reg(2) xor crc_reg(4) xor 
                 crc_reg(5) xor crc_reg(6) xor crc_reg(7) xor crc_reg(8) xor crc_reg(11) xor crc_reg(14) xor 
                 crc_reg(20) xor crc_reg(21) xor crc_reg(22) xor crc_reg(25) xor crc_reg(29) xor crc_reg(30);
    next_crc(7) <= data_in(29) xor data_in(28) xor data_in(25) xor data_in(24) xor data_in(23) xor data_in(22) xor 
                 data_in(21) xor data_in(16) xor data_in(15) xor data_in(10) xor data_in(8) xor data_in(7) xor 
                 data_in(5) xor data_in(3) xor data_in(2) xor data_in(0) xor crc_reg(0) xor crc_reg(2) xor 
                 crc_reg(3) xor crc_reg(5) xor crc_reg(7) xor crc_reg(8) xor crc_reg(10) xor crc_reg(15) xor 
                 crc_reg(16) xor crc_reg(21) xor crc_reg(22) xor crc_reg(23) xor crc_reg(24) xor crc_reg(25) xor 
                 crc_reg(28) xor crc_reg(29);
    next_crc(8) <= data_in(31) xor data_in(28) xor data_in(23) xor data_in(22) xor data_in(17) xor data_in(12) xor 
                 data_in(11) xor data_in(10) xor data_in(8) xor data_in(4) xor data_in(3) xor data_in(1) xor 
                 data_in(0) xor crc_reg(0) xor crc_reg(1) xor crc_reg(3) xor crc_reg(4) xor crc_reg(8) xor 
                 crc_reg(10) xor crc_reg(11) xor crc_reg(12) xor crc_reg(17) xor crc_reg(22) xor crc_reg(23) xor 
                 crc_reg(28) xor crc_reg(31);
    next_crc(9) <= data_in(29) xor data_in(24) xor data_in(23) xor data_in(18) xor data_in(13) xor data_in(12) xor 
                 data_in(11) xor data_in(9) xor data_in(5) xor data_in(4) xor data_in(2) xor data_in(1) xor 
                 crc_reg(1) xor crc_reg(2) xor crc_reg(4) xor crc_reg(5) xor crc_reg(9) xor crc_reg(11) xor 
                 crc_reg(12) xor crc_reg(13) xor crc_reg(18) xor crc_reg(23) xor crc_reg(24) xor crc_reg(29);
    next_crc(10) <= data_in(31) xor data_in(29) xor data_in(28) xor data_in(26) xor data_in(19) xor data_in(16) xor 
                  data_in(14) xor data_in(13) xor data_in(9) xor data_in(5) xor data_in(3) xor data_in(2) xor 
                  data_in(0) xor crc_reg(0) xor crc_reg(2) xor crc_reg(3) xor crc_reg(5) xor crc_reg(9) xor 
                  crc_reg(13) xor crc_reg(14) xor crc_reg(16) xor crc_reg(19) xor crc_reg(26) xor crc_reg(28) xor 
                  crc_reg(29) xor crc_reg(31);
    next_crc(11) <= data_in(31) xor data_in(28) xor data_in(27) xor data_in(26) xor data_in(25) xor data_in(24) xor 
                  data_in(20) xor data_in(17) xor data_in(16) xor data_in(15) xor data_in(14) xor data_in(12) xor 
                  data_in(9) xor data_in(4) xor data_in(3) xor data_in(1) xor data_in(0) xor crc_reg(0) xor 
                  crc_reg(1) xor crc_reg(3) xor crc_reg(4) xor crc_reg(9) xor crc_reg(12) xor crc_reg(14) xor 
                  crc_reg(15) xor crc_reg(16) xor crc_reg(17) xor crc_reg(20) xor crc_reg(24) xor crc_reg(25) xor 
                  crc_reg(26) xor crc_reg(27) xor crc_reg(28) xor crc_reg(31);
    next_crc(12) <= data_in(31) xor data_in(30) xor data_in(27) xor data_in(24) xor data_in(21) xor data_in(18) xor 
                  data_in(17) xor data_in(15) xor data_in(13) xor data_in(12) xor data_in(9) xor data_in(6) xor 
                  data_in(5) xor data_in(4) xor data_in(2) xor data_in(1) xor data_in(0) xor crc_reg(0) xor 
                  crc_reg(1) xor crc_reg(2) xor crc_reg(4) xor crc_reg(5) xor crc_reg(6) xor crc_reg(9) xor 
                  crc_reg(12) xor crc_reg(13) xor crc_reg(15) xor crc_reg(17) xor crc_reg(18) xor crc_reg(21) xor 
                  crc_reg(24) xor crc_reg(27) xor crc_reg(30) xor crc_reg(31);
    next_crc(13) <= data_in(31) xor data_in(28) xor data_in(25) xor data_in(22) xor data_in(19) xor data_in(18) xor 
                  data_in(16) xor data_in(14) xor data_in(13) xor data_in(10) xor data_in(7) xor data_in(6) xor 
                  data_in(5) xor data_in(3) xor data_in(2) xor data_in(1) xor crc_reg(1) xor crc_reg(2) xor 
                  crc_reg(3) xor crc_reg(5) xor crc_reg(6) xor crc_reg(7) xor crc_reg(10) xor crc_reg(13) xor 
                  crc_reg(14) xor crc_reg(16) xor crc_reg(18) xor crc_reg(19) xor crc_reg(22) xor crc_reg(25) xor 
                  crc_reg(28) xor crc_reg(31);
    next_crc(14) <= data_in(29) xor data_in(26) xor data_in(23) xor data_in(20) xor data_in(19) xor data_in(17) xor 
                  data_in(15) xor data_in(14) xor data_in(11) xor data_in(8) xor data_in(7) xor data_in(6) xor 
                  data_in(4) xor data_in(3) xor data_in(2) xor crc_reg(2) xor crc_reg(3) xor crc_reg(4) xor 
                  crc_reg(6) xor crc_reg(7) xor crc_reg(8) xor crc_reg(11) xor crc_reg(14) xor crc_reg(15) xor 
                  crc_reg(17) xor crc_reg(19) xor crc_reg(20) xor crc_reg(23) xor crc_reg(26) xor crc_reg(29);
    next_crc(15) <= data_in(30) xor data_in(27) xor data_in(24) xor data_in(21) xor data_in(20) xor data_in(18) xor 
                  data_in(16) xor data_in(15) xor data_in(12) xor data_in(9) xor data_in(8) xor data_in(7) xor 
                  data_in(5) xor data_in(4) xor data_in(3) xor crc_reg(3) xor crc_reg(4) xor crc_reg(5) xor 
                  crc_reg(7) xor crc_reg(8) xor crc_reg(9) xor crc_reg(12) xor crc_reg(15) xor crc_reg(16) xor 
                  crc_reg(18) xor crc_reg(20) xor crc_reg(21) xor crc_reg(24) xor crc_reg(27) xor crc_reg(30);
    next_crc(16) <= data_in(30) xor data_in(29) xor data_in(26) xor data_in(24) xor data_in(22) xor data_in(21) xor 
                  data_in(19) xor data_in(17) xor data_in(13) xor data_in(12) xor data_in(8) xor data_in(5) xor 
                  data_in(4) xor data_in(0) xor crc_reg(0) xor crc_reg(4) xor crc_reg(5) xor crc_reg(8) xor 
                  crc_reg(12) xor crc_reg(13) xor crc_reg(17) xor crc_reg(19) xor crc_reg(21) xor crc_reg(22) xor 
                  crc_reg(24) xor crc_reg(26) xor crc_reg(29) xor crc_reg(30);
    next_crc(17) <= data_in(31) xor data_in(30) xor data_in(27) xor data_in(25) xor data_in(23) xor data_in(22) xor 
                  data_in(20) xor data_in(18) xor data_in(14) xor data_in(13) xor data_in(9) xor data_in(6) xor 
                  data_in(5) xor data_in(1) xor crc_reg(1) xor crc_reg(5) xor crc_reg(6) xor crc_reg(9) xor 
                  crc_reg(13) xor crc_reg(14) xor crc_reg(18) xor crc_reg(20) xor crc_reg(22) xor crc_reg(23) xor 
                  crc_reg(25) xor crc_reg(27) xor crc_reg(30) xor crc_reg(31);
    next_crc(18) <= data_in(31) xor data_in(28) xor data_in(26) xor data_in(24) xor data_in(23) xor data_in(21) xor 
                  data_in(19) xor data_in(15) xor data_in(14) xor data_in(10) xor data_in(7) xor data_in(6) xor 
                  data_in(2) xor crc_reg(2) xor crc_reg(6) xor crc_reg(7) xor crc_reg(10) xor crc_reg(14) xor 
                  crc_reg(15) xor crc_reg(19) xor crc_reg(21) xor crc_reg(23) xor crc_reg(24) xor crc_reg(26) xor 
                  crc_reg(28) xor crc_reg(31);
    next_crc(19) <= data_in(29) xor data_in(27) xor data_in(25) xor data_in(24) xor data_in(22) xor data_in(20) xor 
                  data_in(16) xor data_in(15) xor data_in(11) xor data_in(8) xor data_in(7) xor data_in(3) xor 
                  crc_reg(3) xor crc_reg(7) xor crc_reg(8) xor crc_reg(11) xor crc_reg(15) xor crc_reg(16) xor 
                  crc_reg(20) xor crc_reg(22) xor crc_reg(24) xor crc_reg(25) xor crc_reg(27) xor crc_reg(29);
    next_crc(20) <= data_in(30) xor data_in(28) xor data_in(26) xor data_in(25) xor data_in(23) xor data_in(21) xor 
                  data_in(17) xor data_in(16) xor data_in(12) xor data_in(9) xor data_in(8) xor data_in(4) xor 
                  crc_reg(4) xor crc_reg(8) xor crc_reg(9) xor crc_reg(12) xor crc_reg(16) xor crc_reg(17) xor 
                  crc_reg(21) xor crc_reg(23) xor crc_reg(25) xor crc_reg(26) xor crc_reg(28) xor crc_reg(30);
    next_crc(21) <= data_in(31) xor data_in(29) xor data_in(27) xor data_in(26) xor data_in(24) xor data_in(22) xor 
                  data_in(18) xor data_in(17) xor data_in(13) xor data_in(10) xor data_in(9) xor data_in(5) xor 
                  crc_reg(5) xor crc_reg(9) xor crc_reg(10) xor crc_reg(13) xor crc_reg(17) xor crc_reg(18) xor 
                  crc_reg(22) xor crc_reg(24) xor crc_reg(26) xor crc_reg(27) xor crc_reg(29) xor crc_reg(31);
    next_crc(22) <= data_in(31) xor data_in(29) xor data_in(27) xor data_in(26) xor data_in(24) xor data_in(23) xor 
                  data_in(19) xor data_in(18) xor data_in(16) xor data_in(14) xor data_in(12) xor data_in(11) xor 
                  data_in(9) xor data_in(0) xor crc_reg(0) xor crc_reg(9) xor crc_reg(11) xor crc_reg(12) xor 
                  crc_reg(14) xor crc_reg(16) xor crc_reg(18) xor crc_reg(19) xor crc_reg(23) xor crc_reg(24) xor 
                  crc_reg(26) xor crc_reg(27) xor crc_reg(29) xor crc_reg(31);
    next_crc(23) <= data_in(31) xor data_in(29) xor data_in(27) xor data_in(26) xor data_in(20) xor data_in(19) xor 
                  data_in(17) xor data_in(16) xor data_in(15) xor data_in(13) xor data_in(9) xor data_in(6) xor 
                  data_in(1) xor data_in(0) xor crc_reg(0) xor crc_reg(1) xor crc_reg(6) xor crc_reg(9) xor 
                  crc_reg(13) xor crc_reg(15) xor crc_reg(16) xor crc_reg(17) xor crc_reg(19) xor crc_reg(20) xor 
                  crc_reg(26) xor crc_reg(27) xor crc_reg(29) xor crc_reg(31);
    next_crc(24) <= data_in(30) xor data_in(28) xor data_in(27) xor data_in(21) xor data_in(20) xor data_in(18) xor 
                  data_in(17) xor data_in(16) xor data_in(14) xor data_in(10) xor data_in(7) xor data_in(2) xor 
                  data_in(1) xor crc_reg(1) xor crc_reg(2) xor crc_reg(7) xor crc_reg(10) xor crc_reg(14) xor 
                  crc_reg(16) xor crc_reg(17) xor crc_reg(18) xor crc_reg(20) xor crc_reg(21) xor crc_reg(27) xor 
                  crc_reg(28) xor crc_reg(30);
    next_crc(25) <= data_in(31) xor data_in(29) xor data_in(28) xor data_in(22) xor data_in(21) xor data_in(19) xor 
                  data_in(18) xor data_in(17) xor data_in(15) xor data_in(11) xor data_in(8) xor data_in(3) xor 
                  data_in(2) xor crc_reg(2) xor crc_reg(3) xor crc_reg(8) xor crc_reg(11) xor crc_reg(15) xor 
                  crc_reg(17) xor crc_reg(18) xor crc_reg(19) xor crc_reg(21) xor crc_reg(22) xor crc_reg(28) xor 
                  crc_reg(29) xor crc_reg(31);
    next_crc(26) <= data_in(31) xor data_in(28) xor data_in(26) xor data_in(25) xor data_in(24) xor data_in(23) xor 
                  data_in(22) xor data_in(20) xor data_in(19) xor data_in(18) xor data_in(10) xor data_in(6) xor 
                  data_in(4) xor data_in(3) xor data_in(0) xor crc_reg(0) xor crc_reg(3) xor crc_reg(4) xor 
                  crc_reg(6) xor crc_reg(10) xor crc_reg(18) xor crc_reg(19) xor crc_reg(20) xor crc_reg(22) xor 
                  crc_reg(23) xor crc_reg(24) xor crc_reg(25) xor crc_reg(26) xor crc_reg(28) xor crc_reg(31);
    next_crc(27) <= data_in(29) xor data_in(27) xor data_in(26) xor data_in(25) xor data_in(24) xor data_in(23) xor 
                  data_in(21) xor data_in(20) xor data_in(19) xor data_in(11) xor data_in(7) xor data_in(5) xor 
                  data_in(4) xor data_in(1) xor crc_reg(1) xor crc_reg(4) xor crc_reg(5) xor crc_reg(7) xor 
                  crc_reg(11) xor crc_reg(19) xor crc_reg(20) xor crc_reg(21) xor crc_reg(23) xor crc_reg(24) xor 
                  crc_reg(25) xor crc_reg(26) xor crc_reg(27) xor crc_reg(29);
    next_crc(28) <= data_in(30) xor data_in(28) xor data_in(27) xor data_in(26) xor data_in(25) xor data_in(24) xor 
                  data_in(22) xor data_in(21) xor data_in(20) xor data_in(12) xor data_in(8) xor data_in(6) xor 
                  data_in(5) xor data_in(2) xor crc_reg(2) xor crc_reg(5) xor crc_reg(6) xor crc_reg(8) xor 
                  crc_reg(12) xor crc_reg(20) xor crc_reg(21) xor crc_reg(22) xor crc_reg(24) xor crc_reg(25) xor 
                  crc_reg(26) xor crc_reg(27) xor crc_reg(28) xor crc_reg(30);
    next_crc(29) <= data_in(31) xor data_in(29) xor data_in(28) xor data_in(27) xor data_in(26) xor data_in(25) xor 
                  data_in(23) xor data_in(22) xor data_in(21) xor data_in(13) xor data_in(9) xor data_in(7) xor 
                  data_in(6) xor data_in(3) xor crc_reg(3) xor crc_reg(6) xor crc_reg(7) xor crc_reg(9) xor 
                  crc_reg(13) xor crc_reg(21) xor crc_reg(22) xor crc_reg(23) xor crc_reg(25) xor crc_reg(26) xor 
                  crc_reg(27) xor crc_reg(28) xor crc_reg(29) xor crc_reg(31);
    next_crc(30) <= data_in(30) xor data_in(29) xor data_in(28) xor data_in(27) xor data_in(26) xor data_in(24) xor 
                  data_in(23) xor data_in(22) xor data_in(14) xor data_in(10) xor data_in(8) xor data_in(7) xor 
                  data_in(4) xor crc_reg(4) xor crc_reg(7) xor crc_reg(8) xor crc_reg(10) xor crc_reg(14) xor 
                  crc_reg(22) xor crc_reg(23) xor crc_reg(24) xor crc_reg(26) xor crc_reg(27) xor crc_reg(28) xor 
                  crc_reg(29) xor crc_reg(30);
    next_crc(31) <= data_in(31) xor data_in(30) xor data_in(29) xor data_in(28) xor data_in(27) xor data_in(25) xor 
                  data_in(24) xor data_in(23) xor data_in(15) xor data_in(11) xor data_in(9) xor data_in(8) xor 
                  data_in(5) xor crc_reg(5) xor crc_reg(8) xor crc_reg(9) xor crc_reg(11) xor crc_reg(15) xor 
                  crc_reg(23) xor crc_reg(24) xor crc_reg(25) xor crc_reg(27) xor crc_reg(28) xor crc_reg(29) xor 
                  crc_reg(30) xor crc_reg(31);

end behav;
